package dao

import (
	"context"
	"prod/api/prod"
	"prod/internal/model"
)

func (d *Dao) LoadProdTypeListWithCount(ctx context.Context, sgId, pStoreId uint32, nature prod.Nature) (
	prodTypes []*model.ProdTypeQueryModel, err error) {
	db := d.TransContext(ctx).Model(&model.ProdType{}).Select(
		"pd_prod_type.id, pd_prod_type.name, count(pd_product.id) as count, parent_id").Joins(
		"LEFT OUTER JOIN pd_product ON type_id = pd_prod_type.id AND pd_product.status=true").Where(
		"pd_prod_type.sg_id = ? AND pd_prod_type.p_store_id = ? AND pd_prod_type.status = ?",
		sgId, pStoreId, true)
	if nature != prod.Nature_NATURE_ALL {
		db = db.Where("pd_prod_type.nature = ? ", int(nature))
	}
	if err = db.Group("pd_prod_type.id").Order(
		"pd_prod_type.id asc").Scan(&prodTypes).Error; err != nil {
		err = d.processSqlError(err)
		return
	}
	return
}

func (d *Dao) LoadProdStatsByNature(ctx context.Context, sgId, pStoreId uint32) (
	natureViews []*prod.NatureView, err error) {
	if err = d.TransContext(ctx).Model(&model.Product{}).Select(
		"nature, count(id) as count").Group("nature").Find(&natureViews,
		"sg_id = ? AND p_store_id = ? AND status = ?",
		sgId, pStoreId, true).Error; err != nil {
		err = d.processSqlError(err)
		return
	}
	return
}

func (d *Dao) GetProdTypeByID(ctx context.Context, id, sgId, pStoreId uint32) (
	prodType *model.ProdType, err error) {
	prodType = &model.ProdType{}
	if err = d.TransContext(ctx).Take(prodType,
		"id=? AND sg_id=? AND p_store_id=? AND status=?",
		id, sgId, pStoreId, true).Error; err != nil {
		err = d.processSqlError(err)
	}
	return
}

func (d *Dao) GetProdTypeByName(ctx context.Context, name string, sgId, pStoreId, parentId uint32) (
	prodType *model.ProdType, err error) {
	prodType = &model.ProdType{}
	if err = d.TransContext(ctx).Take(prodType,
		"sg_id=? AND p_store_id=? AND parent_id=? AND name=?",
		sgId, pStoreId, parentId, name).Error; err != nil {
		err = d.processSqlError(err)
	}
	return
}

func (d *Dao) ReplaceProdType(ctx context.Context, rawId, targetId, operator uint32) (err error) {
	if err = d.TransContext(ctx).Model(&model.Product{}).Where(
		"type_id=? AND status=?",
		rawId, true).Updates(map[string]interface{}{
		"type_id":  targetId,
		"operator": operator,
	}).Error; err != nil {
		err = d.processSqlError(err)
		return
	}
	return
}

func (d *Dao) GetSubTypes(ctx context.Context, sgId, pStoreId, parentId uint32) (subTypes []*model.ProdType, err error) {
	if err = d.TransContext(ctx).Model(&model.ProdType{}).Where(
		"sg_id = ? AND p_store_id = ? AND parent_id = ? AND status = ?",
		sgId, pStoreId, parentId, true).Scan(&subTypes).Error; err != nil {
		err = d.processSqlError(err)
		return
	}
	return
}

func (d *Dao) GetSimpleProdTypeList(ctx context.Context, sgId, pStoreId uint32) (
	prodTypes []*prod.SimpleProdTypeView, err error) {
	if err = d.TransContext(ctx).Table("pd_prod_type p1").Joins(
		"JOIN pd_prod_type p2 ON p1.parent_id = p2.id").Select(
		"p1.id, CONCAT(p2.name, '/' , p1.name) as name, p1.p_store_id").Where(
		"p1.sg_id = ? AND p1.p_store_id = ? AND p1.parent_id > 0 AND p1.status=true",
		sgId, pStoreId, true).Scan(&prodTypes).Error; err != nil {
		err = d.processSqlError(err)
	}
	return
}

func (d *Dao) GetSimpleProdTypeByIDs(ctx context.Context, ids []uint32, sgId, pStoreId uint32) (
	prodTypes []*prod.SimpleProdTypeView, err error) {
	if len(ids) == 0 {
		return
	}
	if err = d.TransContext(ctx).Table("pd_prod_type p1").Joins(
		"JOIN pd_prod_type p2 ON p1.parent_id = p2.id").Select(
		"p1.id, CONCAT(p2.name, '/' , p1.name) as name").Where(
		"p1.id in ? AND p1.sg_id = ? AND p1.p_store_id = ? AND p1.status= ? ",
		ids, sgId, pStoreId, true).Scan(&prodTypes).Error; err != nil {
		err = d.processSqlError(err)
	}
	return
}

func (d *Dao) GetSimpleProdTypeByIDsWithoutPStoreId(ctx context.Context, ids []uint32, sgId uint32) (
	prodTypes []*prod.SimpleProdTypeView, err error) {
	if len(ids) == 0 {
		return
	}
	if err = d.TransContext(ctx).Table("pd_prod_type p1").Joins(
		"JOIN pd_prod_type p2 ON p1.parent_id = p2.id").Select(
		"p1.id, CONCAT(p2.name, '/' , p1.name) as name, p1.p_store_id").Where(
		"p1.id in ? AND p1.sg_id = ? AND p1.status= ? ",
		ids, sgId, true).Scan(&prodTypes).Error; err != nil {
		err = d.processSqlError(err)
	}
	return
}
